﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.AspNetCore;
using Abp.Castle.Logging.Log4Net;
using Castle.Facilities.Logging;
using IdentityModel;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace NRSoft.IdentityServer.ClientA
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            // 集成IdentityServer4的SSO方案的配置
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })
            .AddCookie()
            .AddOpenIdConnect(options =>
            {
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.RequireHttpsMetadata = true;
                options.Authority = "https://qasso.avischina.cn";
                //options.Authority = "https://localhost:44300";

                options.ClientId = "clientA";
                options.ClientSecret = "secret";
                options.ResponseType = OidcConstants.ResponseTypes.CodeIdTokenToken;

                /* 这里我们使用的是implicit这个flow（隐式许可），
                 * 它主要用于客户端应用程序（主要指基于javascript的应用），
                 * 它允许客户端程序重定向到AuthorizationServer，然后带着token重定向回来。
                 * 值得一提的是这里的ResponseType为"id_token token"，
                 * 表示既获取id_token也获取access_token。
                 * 而SaveTokens设为true则表示要将从AuthorizationServer返回的token持久化在cookie之中，
                 * 这样就不用每次都去请求token了。
                 * 网址：http://www.cnblogs.com/edisonchou/archive/2018/06/25/9219767.html
                 */
                // lulus:允许在cookies里面存储id_token和access_token等
                options.SaveTokens = true;
                // lulus:登出后,sso默认回调/signout-callback-oidc清空cookies,清空之后返回的最终的地址就是下面的地址
                options.SignedOutRedirectUri = "/home/about";

                //options.GetClaimsFromUserInfoEndpoint = true;
                //options.Scope.Add("api1");
                //options.Scope.Add("offline_access");
            });

            // 配置ABP和依赖注入。应该在最后执行。
            return services.AddAbp<ClientAWebModule>(options =>
            {
                // 配置Log4net日志记录（可选）
                options.IocManager.IocContainer.AddFacility<LoggingFacility>(
                    f => f.UseAbpLog4Net().WithConfig("log4net.config")
                );
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // 初始化ABP框架和所有模块（module）。必须要先执行
            app.UseAbp();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            // 启用验证中间件
            app.UseAuthentication();

            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            //app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}
